epci_fonds_fm <- st_read("C:/Users/Rania El Fahli/Documents/Fonds de carte IGN 2023/EPCI.shp")
## Reading layer `EPCI' from data source 
##   `C:\Users\Rania El Fahli\Documents\Fonds de carte IGN 2023\EPCI.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 1243 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 107388.8 ymin: 6046546 xmax: 1242443 ymax: 7110479
## Projected CRS: RGF93 Lambert 93
dep_fm <- st_read("C:/Users/Rania El Fahli/Documents/Fonds de carte IGN 2023/DEPARTEMENT.shp")
## Reading layer `DEPARTEMENT' from data source 
##   `C:\Users\Rania El Fahli\Documents\Fonds de carte IGN 2023\DEPARTEMENT.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 96 features and 5 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 99040 ymin: 6046546 xmax: 1242443 ymax: 7110479
## Projected CRS: RGF93 Lambert 93
epci_fonds_fm <- epci_fonds_fm |>
  dplyr::filter(NATURE != "Etablissement public territorial")

# check projection 
# st_crs(epci_fonds_fm)
# st_crs(dep_fm)
donnes_stat_locales <- list.files("C:/Users/Rania El Fahli/Documents/tuto_carto/tuto_carto", pattern = "*.xlsx", 
                                  full.names = TRUE)
donnes_stat_locales_f <-  lapply(donnes_stat_locales, function(x) read_excel(x, skip = 3))

source("C:/Users/Rania El Fahli/Documents/Atlas/Cartes/Scripts/codes_epci_dom.R") # vecteur contenant les codes des EPCI d'Outre-Mer pour filtrer + facilement.

rename_colonne <- function(x) { 
  names(x) <- str_replace(names(x), "Part des familles monoparentales ", "part_fam_mono_")
  return(x)
  
}
donnes_stat_locales_f <- donnes_stat_locales_f |>
  lapply(rename_colonne)

donnes_stat_locales_f <- lapply(donnes_stat_locales_f, function(x) filter(x, !Code %in% epci_dom))
donnes_stat_locales_f <- lapply(donnes_stat_locales_f, function(x)select(x, -c(Libellé)))
donnes_serie_epci_fm <- plyr::join_all(donnes_stat_locales_f, by = "Code", type = "left")
donnes_serie_epci_fm <- donnes_serie_epci_fm |>
  mutate_at(vars(starts_with("part_fam_mono")), as.numeric)
donnes_long <- donnes_serie_epci_fm |>
  pivot_longer(!c(Code), 
               names_to = "annee", 
               values_to = "part_fam_mono")

discret_jenks <- classInt::classIntervals(donnes_long$part_fam_mono, style = "jenks", n = 4)
discret_jenks_v <- c(4.4, 10.0, 12.7, 15.7, 22.5)
palette <- rcartocolor::carto_pal(n = 4, name = "PinkYl")
donnes_carto <- epci_fonds_fm |>
  left_join(donnes_serie_epci_fm, by = c("CODE_SIREN" = "Code"))

Cas 1 : “Faceter” une carte

Le “faceting” permet de générer un graphique/carte pour chaque groupe de la variable utilisée. Cela reviendrait à subset la table principale par groupe et réaliser la même carte à partir de chacune de ces sous-tables. Avec {ggplot2}, on utilise la fonction facet_wrap().

En amont, on transforme la table au format long pour créer une variable année qui contient trois groupes correspondant aux 3 années de la table principale : 2009, 2014 et 2020.

# on transforme la table au format long pour avoir une variable "année" qu'on utilise 
# ensuite pour le faceting 

donnes_carto_l <- donnes_carto |>
  select(c(CODE_SIREN, geometry, starts_with("part_fam_mono"))) |>
   pivot_longer(!c(CODE_SIREN, geometry), 
               names_to = "annee",
               values_to = "part_fam_mono") 

donnes_carto_l$annee <- as.factor(donnes_carto_l$annee)
donnes_carto_l$annee <- donnes_carto_l$annee |>
  forcats::fct_recode(
     "2009" = "part_fam_mono_2009",
     "2014" = "part_fam_mono_2014",
     "2020" = "part_fam_mono_2020"
  ) # on modifie les données pour l'affichage des labels ensuite 

Avec Ggplot2

theme_carte_rania <- theme(
  panel.background = element_blank(), 
          panel.grid = element_blank(),
          axis.line = element_blank(), 
          axis.text.x = element_blank(), 
          axis.text.y = element_blank(), 
          axis.ticks.x = element_blank(), 
          axis.ticks.y = element_blank(), 
          legend.box = "vertical",
          legend.key.width = unit(0.4, "cm"), 
          legend.key.height = unit(1, "cm"),
          legend.key = element_rect(colour = "transparent",), 
          legend.background = element_rect(fill='transparent', colour = "grey35", size = 0.8),
          legend.title = element_text(size = 18),
          legend.text = element_text(size = 16), 
          legend.key.size = unit(1.7,'cm'),
          legend.spacing.y = unit(1.3, 'cm'),
          legend.title.align = 0,
  plot.title = element_text(size = 22, face = "bold"), 
  plot.subtitle = element_text(size = 20, face = "bold"), 
  plot.caption = element_text(size = 12, hjust = 0, face = "italic"), 
  # élements relatifs aux labels du facet_wrap 
  strip.background =  element_rect(
  color="grey35", fill="transparent", size=0.8, linetype="solid"), 
  strip.text = element_text(size = 18, face = "bold.italic")
)
donnes_carto_l$discret <-  cut(donnes_carto_l$part_fam_mono, c(discret_jenks_v))

mes_labels <- function(breaks) {
    do.call(\(...) sprintf('De %s à %s', ...),
            cbind.data.frame(breaks[-length(breaks)] , breaks[-1]))
}

labels_fam_mono <- mes_labels(discret_jenks[["brks"]])
p <- donnes_carto_l |>
  ggplot() + 
  geom_sf(aes(fill = discret),color = "grey55", lwd = 0.2 ) +
  scale_fill_manual(values = palette, labels = labels_fam_mono)+
  geom_sf(data= dep_fm, fill = "transparent", color = "grey35", lwd = 0.5) +
  labs(fill = "Part des familles monoparentales (%)", 
       title = "Evolution de la part des familles monoparentales entre 2009 et 2020", 
       subtitle = "A l'échelle des EPCI", 
       caption = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.", 
                        sep = "\n", "IGN 2023.")) +
  theme_carte_rania  +
  facet_wrap(~annee, nrow = 2, ncol = 2) + # modifier les arguments nrow et ncol pour changer la disposition des cartes
guides(fill = guide_legend(title.position="top", title.hjust = 0)) 
# lemon::reposition_legend() pour changer la disposition de la légende (utiliser les espaces vides)
lemon::reposition_legend(p, "center", panel = "panel-2-2")

Avec Tmap

Si les cartes sont réalisées avec le package {tmap}, l’équivalent est tm_facets()

donnes_carto_l |>
  tm_shape() +
  tm_polygons("part_fam_mono", style = "jenks", n = 4, palette = palette,
              border.col = "grey55", lwd = 0.2, 
              labels = c("4,5 à 10", "10 à 12,7", "12,7 à 15,7", "15,7 à 22,5"), 
              title = "Part des familles monoparentales (%)")+ 
  tm_facets("annee")  +
  tm_layout(
    main.title = paste0("Evolution de la part des familles monoparentales entre 2009 et 2020", 
                   sep = "\n","A l'échelle des EPCI" ),
   main.title.size = 2, 
   main.title.fontface = "bold", 
   main.title.position = c("left", "top"),
    panel.label.fontface = "bold", 
    panel.label.bg.color = "white",
    panel.label.color = "grey35", 
    panel.label.size = 3,
    legend.title.size = 10, 
    legend.text.size = 2,
    legend.frame = F
  ) # changer au choix l'afficage du panel avec les arguments de tm_layout()
Générer plusieurs cartes avec tm_facets

Générer plusieurs cartes avec tm_facets

Avec Mapsf

On utilise les fonctions de base R, mfrow() et par().

Voir les exemples de la vignette du package : Faceting with Mapsf Package : https://riatelab.github.io/mapsf/articles/web_only/how_to_create_faceted_maps.html

Cas 2 : Arranger des cartes individuelles

Dans le cas où les cartes sont réalisées individuellement (elles ne dépendent pas d’une même table), différents packages permettent de les arranger sur une même image :

# je génère deux cartes individuelles pour l'exemple 
# je retire le titre & la caption que je rajouterai sur l'image finale

carte_2009 <- donnes_carto_l |>
  dplyr::filter(annee == "2009") |>
  ggplot() + 
  geom_sf(aes(fill = discret),color = "grey55", lwd = 0.2 ) +
  scale_fill_manual(values = palette, labels = labels_fam_mono)+
  geom_sf(data= dep_fm, fill = "transparent", color = "grey35", lwd = 0.5) +
  labs(fill = "Part des familles monoparentales (%)") +
  theme_carte_rania  + 
  guides(fill = guide_legend(title.position="top", title.hjust = 0)) 

carte_2020 <- donnes_carto_l |>
  dplyr::filter(annee == "2020") |>
  ggplot() + 
  geom_sf(aes(fill = discret),color = "grey55", lwd = 0.2 ) +
  scale_fill_manual(values = palette, labels = labels_fam_mono)+
  geom_sf(data= dep_fm, fill = "transparent", color = "grey35", lwd = 0.5) +
  labs(fill = "Part des familles monoparentales (%)") +
  theme_carte_rania  +
  guides(fill = guide_legend(title.position="top", title.hjust = 0)) 

Exemple Patchwork :

# guide_area() permet de créer un espace vide pour y placer la légende, sinon elle est placée par défaut comme ici.
# (carte_2009 + carte_2020) / guide_area() = les deux cartes côte à côte sur une première ligne, 

(carte_2009 + carte_2020) +
  plot_layout(guides = "collect") + 
  plot_annotation(
    title = "Evolution de la part des familles monoparentales entre 2009 et 2020", 
    subtitle = "A l'échelle des EPCI", 
    caption = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.", 
                        sep = "\n", "IGN 2023."),
    tag_levels = list(c("2009", "2020")), 
    theme = theme(
    plot.caption = element_text(size = 22, face = "italic" ), 
    plot.title = element_text(size = 30), 
    plot.subtitle = element_text(size = 30),  # on peut utiliser directement la fonction theme() de ggplot2 pour personnaliser la mise en forme des différents éléments.
  )) & theme(plot.tag = element_text(size = 30))
Assembler les cartes avec Patchwork

Assembler les cartes avec Patchwork

Exemple Cowplot :

Ici il vaut mieux extraire la légende en amont et enregistrer à nouveaux les cartes sans légende.

legende <- ggpubr::get_legend(carte_2009)

carte_2009 <- carte_2009 + 
  theme(legend.position = "none")
carte_2020 <- carte_2020 + 
  theme(legend.position = "none")
deux_cartes <- plot_grid(carte_2009 , carte_2020 ) # on met les cartes côte à côte
# on assemble les éléments 
deux_cartes_legende <-  ggdraw() +
    draw_plot(deux_cartes) +
    draw_plot(legende, scale = 2, 
              x = -0.02, 
              y = 0.05)

# ggdraw() permet d'assembler différents types d'objets (labels, ggplots, tables gt, images)
# Pour les différents éléments on peut utiliser ggdraw et draw_labels, ou bien enregistrer les cartes assemblées puis utiliser annotate()

deux_cartes_legende + 
    annotate(geom = "text", 
             label = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.", 
                        sep = "\n", "IGN 2023."), 
             fontface = 'italic', 
             x  = 0.85, y = 0.02, size = 5 ) +
    annotate(geom = "text", 
             label = paste0("Evolution de la part des familles monoparentales entre 2009 et 2020", sep = "\n", 
                           "A l'échelle des EPCI"),
             y = 0.95, x = 0.47, size = 8 , 
             fontface = "bold") +
    annotate(geom = "text", 
             label = "2009", 
             x = 0.118, y = 0.85, 
             fontface = "italic", 
             size = 10
    ) +
    annotate(geom = "text", 
             label = "2020", 
             fontface = "italic", 
             size = 10, 
             y = 0.85, x = 0.62) 
Assembler les cartes avec Cowplot - méthode 1

Assembler les cartes avec Cowplot - méthode 1

ggdraw() permet de choisir plus précisement ici la taille et le ratio des éléments. On aurait pu sinon réaliser la carte ainsi, toujours avec Cowplot :

deux_cartes_legende <- plot_grid(carte_2009, legende, carte_2020, 
          align = "vh", 
          nrow = 1, 
          rel_widths = c(3, 0.85, 3)) # le ratio de chaque élément

deux_cartes_legende + annotate(geom = "text", 
             label = paste0("Source : Recensement de la population, exploitation complémentaire, Insee.", 
                        sep = "\n", "IGN 2023."), 
             fontface = 'italic', 
             x  = 0.85, y = 0.02, size = 5 ) +
    annotate(geom = "text", 
             label = paste0("Evolution de la part des familles monoparentales entre 2009 et 2020", sep = "\n", 
                           "A l'échelle des EPCI"),
             y = 0.95, x = 0.47, size = 8 , 
             fontface = "bold") +
    annotate(geom = "text", 
             label = "2009", 
             x = 0.118, y = 0.85, 
             fontface = "italic", 
             size = 10
    ) +
    annotate(geom = "text", 
             label = "2020", 
             fontface = "italic", 
             size = 10, 
             y = 0.85, x = 0.62) 
Assembler les cartes avec Cowplot - méthode 2

Assembler les cartes avec Cowplot - méthode 2

Références : Ggplot2: Elegant Graphics for Data Analysis, 9 Arranging plots (https://ggplot2-book.org/arranging-plots), 16 Faceting (https://ggplot2-book.org/facet) Geocomputation with R : https://r.geocompx.org/